package com.atjava.nebula.core.service;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import com.atjava.nebula.core.dao.ibatis.Condition;
import com.atjava.nebula.core.dao.ibatis.projection.IProjection;
import com.atjava.nebula.core.model.BaseModel;
import com.atjava.nebula.core.exception.baseExp.BusinessException;
import com.atjava.nebula.core.exception.baseExp.DataAccessException;
import com.atjava.nebula.core.page.Page;


/**泛型Server接口
 * @author kyo
 *
 * @param <T>
 * @param <ID>
 */
public interface GenericService<T extends BaseModel,ID extends Serializable> {

	/**无条件查询，读取整张表的数据
	 * @return 表对象的集合List
	 * @throws BusinessException
	 */
	List<T> getAll() throws BusinessException;	

	/**增加一条数据记录
	 * @param obj 保存有数据的对象
	 * @return 当主键为自动生成时，会返回主键对象
	 * @throws BusinessException
	 */
	 ID create(T obj) throws BusinessException;	
	
	/**根据主键查询对象
	 * @param id 主键对象
	 * @return 返回一个T类型的结果对象
	 * @throws BusinessException
	 */
	T getById(ID id) throws BusinessException;
	

	/**根据指定的表主键（ID）更新对象，支持部分更新，值为空(null)的属性不进行更新
	 * @param obj 保存更新主键及更新内容的表对象
	 * @throws BusinessException
	 */
	void updateById(T obj) throws BusinessException;
	
	/**根据指定的表主键（ID）更新对象，支持部分更新，值为空(null)的属性也将更新到字段
	 * @param obj 保存更新主键及更新内容的表对象
	 * @throws BusinessException
	 */
	void updateAllById(T obj) throws BusinessException;	
	
	/**按条件批量删除

	 * @param obj 保存删除条件的表对象
	 * @throws BusinessException
	 */
	void remove(T obj) throws BusinessException;
	

	/**根据主键删除数据
	 * @param id 保存删除主键的对象
	 * @throws BusinessException
	 */
	void removeById(ID id) throws BusinessException;
	

	/** 按条件读取数据列表（不进行分页）
	 * @param obj 保存有值的对象，做为查询条件
	 * @return 返回List保存的数据集
	 * @throws BusinessException
	 */
	List<T> list(T obj) throws BusinessException;
	
	/**读取数据列表（不进行分页）
	 * @param cond 查询条件对象
	 * @return  返回List保存的数据集
	 * @throws BusinessException
	 */
	List<T> list(Condition cond) throws BusinessException;
	
	/**支持分组(Group By)及投影的数据列表读取
	 * @param projection 投影参数
	 * @param cond 条件参数
	 * @return 返回List<Map>保存的数据集
	 * @throws BusinessException
	 */
	List<Map<String,Object>> list(IProjection projection,Condition cond) throws BusinessException;
	
	/**支持分组(Group By)及投影的数据列表读取
	 * @param obj  保存有值的对象，做为查询条件
	 * @param projection  投影参数
	 * @return 返回List<Map>保存的数据集
	 * @throws BusinessException
	 */
	List<Map<String,Object>> list(T obj, IProjection projection) throws BusinessException;
	

	/**有条件分页查询
	 * @param obj 要条件的表对象，可包含有条件
	 * @param pageNo 当前页码
	 * @param pageSize 每页记录数
	 * @return 返回一个包含有数据的Page对象
	 * @throws BusinessException
	 */
	Page<T> page(T obj, int pageNo, int pageSize) throws BusinessException;
	
	/**有条件分页查询
	 * @param cond 条件参数
	 * @param pageNo 当前页码
	 * @param pageSize 每页记录数
	 * @return 返回一个包含有数据的Page对象
	 * @throws BusinessException
	 */
	Page<T> page(Condition cond, int pageNo, int pageSize) throws BusinessException;
	
	/**支持分组(Group By)的分页查询
	 * @param projection 投影参数
	 * @param cond 条件参数
	 * @param pageNo 当前页码
	 * @param pageSize 每页记录数
	 * @return  返回一个包含有数据的Page对象
	 * @throws BusinessException
	 */
	Page<Map<String,Object>> page(IProjection projection, Condition cond,
			int pageNo, int pageSize) throws BusinessException ;
	
	/**支持分组(Group By)的分页查询
	 * @param obj 要条件的表对象，可包含有条件
	 * @param projection 投影参数
	 * @param pageNo 当前页码
	 * @param pageSize 每页记录数
	 * @return  返回一个包含有数据的Page对象
	 * @throws BusinessException
	 */
	Page<Map<String,Object>> page(T obj,IProjection projection,
			int pageNo, int pageSize) throws BusinessException ;
	
	/**统计记录数量
	 * @return 返回记录数量
	 * @throws BusinessException
	 */
	Integer count() throws BusinessException;
	
	/**根据条件统计记录数量
	 * @param cond 保存有条件的Condition对象
	 * @return 返回记录数量
	 * @throws BusinessException
	 */
	Integer count(Condition cond) throws BusinessException;
	
	/**根据条件统计记录数量
	 * @param obj 保存有条件的实体对象
	 * @return 返回记录数量
	 * @throws BusinessException
	 */
	Integer count(T obj) throws BusinessException;
	
	/**根据条件统计记录数量，支持分组查询
	 * @param projection 投影参数
	 * @param cond 保存有条件的Condition对象
	 * @return 返回记录数量
	 * @throws BusinessException
	 */
	Integer count(IProjection projection, Condition cond) throws BusinessException;	
	/**根据条件统计记录数量，支持分组查询
	 * @param obj 保存有条件的实体对象
	 * @param projection 投影参数
	 * @return 返回记录数量
	 * @throws BusinessException
	 */
	Integer count(T obj , IProjection projection) throws BusinessException;	

	/**直接执行SQL语句，结果返回到List里
	 * @param sql 要执行的Sql语句 可以是Insert Update等
	 * @return 返回一个保存为Map元素的List
	 * @throws BusinessException
	 */
	List<Map<String,Object>> ExecSql(String sql) throws BusinessException;

	/**
	 * 直接执行SQL语句，结果返回到List里。支持动态条件参数
	 * <br>
	 * 例：ExecSql("select * from addv where addvcd=? and use=?","1000001",true);
	 * @param sql sql 要执行的Sql语句 可以是Insert Update等
	 * @param params 动态参数
	 * @return 返回一个保存为Map元素的List
	 * @throws DataAccessException
	 */
	List<Map<String, Object>> ExecSql(String sql,Object ...params) throws BusinessException;	
	
	/**
	 * 服务拦截器 
	 * @param intercept
	 * @param service
	 */
	void setIntercept(InterceptService intercept);
	
	/**
	 * 在拦截过程中，如果需要调用其他方法，并且该方法也有拦截
	 * 可以设置参数为false。
	 * true为继续拦截
	 * @param flag
	 */
	public void startIntercept(boolean flag);
}
